#include "command.h"

Command_processor::Command_processor () : stats_res (), fr (), r (), tab_ta ()
{
  nv_pos = cv_pos = table_pos = 0;
}

boolean Command_processor::run ()
{
  if (fr.open ('r'))
  {
	process ();
	return TRUE;
  }
  else
	return FALSE;
}

boolean Command_processor::run (string filename)
{
  if (fr.open (filename, 'r'))
  {
	process ();
	return TRUE;
  }
  else
	return FALSE;
}

boolean Command_processor::numvec_create (string name, string min, string max)
{
  float temp_max, temp_min;

  if (! (max.is_float ()) && (min.is_float ()))
  {
	err = invalid_arg;
	return FALSE;
  }

  if (100 == nv_pos)
  {
	cout << "Array is full, cannot add any more vectors." << endl;
	return FALSE;
  }
  else
  {
	nv[nv_pos].set_name (name);
	temp_max = float (max);
	temp_min = float (min);
	if (temp_max > temp_min)
	{
	  nv[nv_pos].set_max (temp_max);
	  nv[nv_pos].set_min (temp_min);
	}
	else
	{
	  nv[nv_pos].set_max (temp_min);
	  nv[nv_pos].set_min (temp_max);
	}
	nv_pos++;
	return TRUE;
  }
}

boolean Command_processor::codevec_create (string name, string allowed[], int num)
{
  if (100 == cv_pos)
  {
	cout << "Array is full, cannot add any more vectors." << endl;
	return FALSE;
  }
  else
  {
	cv[cv_pos].set_name (name);
	for (int i = 0; i < num; i++)
	  cv[cv_pos].add_allowed (allowed[i]);
	cv_pos++;
	return TRUE;
  }
}

void Command_processor::read (string filename)
{
  r.read_data (filename);
}

void Command_processor::cal_stats (const Numvec& data)
{
  stats_res.add_vec (data);
  stats_res.print ();
}

PROCESS_ERR Command_processor::process ()
{
  string word[100], allow[100];
  boolean flag = FALSE;
  int count = fr.next (word, 100), i, acc, temp_pos, temp_val;

  while ((word[0] != "end") || fr.eof ())
  {
	if (word[0] == "read")
	{
	  if (count >= 12)
	  { // takes a maxium of 10 vectors
		cout << "Too many arguements for read." << endl;
		return too_many_arg;
	  }

	  for (i = 2; i < count; i++)
	  {
		if ((temp = find_vec (word[i])) != NULL)
		  r.add_vec (temp);
		else
		{
		  cout << "Invalid vector for read. " << endl;
		  return invalid_arg;
		}
	  }
	  read (word[1]);
	}

	else if (word[0] == "numvec")
	{
	  if (4 <= count)
		numvec_create (word[1], word[2], word[3]);
	  else
	  {
		cout << "Insufficient number of arguements to create a Numvec." << endl;
		return too_few_arg;
	  }
	}

	else if (word[0] == "codevec")
	{
	  acc = 0;

	  // check if the allowable strings are enclosed in braces
	  if ( (word[2] == "{") && (word[count - 1] == "}") )
		for (i = 3; i < (count - 1); i++)
		  allow[acc++] = word[i];
	  else
	  {	// allowable strings are not enclosed in braces
		cout << "Invalid arguements to create a Codevec." << endl;
		return invalid_arg;
	  }
	  codevec_create (word[1], allow, acc);
	}

	else if ((word[0] == "stats") || (word[0] == "statistics"))
	{
	  flag = FALSE;
	  for (i = 0; i < nv_pos; i++)
		if (nv[i].get_name () == word[1])
		{
		  flag = TRUE;
		  cal_stats (nv[i]);
		}
	  if (!flag)
	  {
		cout << "Numeric vector not found!." << endl;
		return invalid_arg;
	  }
	}
	else if (word[0] == "tabulate")
	{
	  if (count != 3)
	  {
		cerr << "Invalid arguements." << endl;
		return invalid_arg;
	  }

	  if (table_pos == 20)
	  {
		cerr << "Table array full!" << endl;
		return size;
	  }
	  else
	  {
		ta[table_pos].name (word[2]);
		tab_ta.tabulate_table (&ta[table_pos], find_vec (word[1]));
		table_pos++;
	  }
	}
	else if (word[0] == "display")
	{
	  if ((count != 2) && (count != 3))
	  {
		cerr << "Invalid arguements." << endl;
		return invalid_arg;
	  }
	  else
	  {
		temp_pos = -1;
		for (i = 0; i < 20; i++)
		  if (ta[i].name () == word[1])
			temp_pos = i;
		if (temp_pos == -1)
		{
		  cerr << "Table not found." << endl;
		  return invalid_arg;
		}
		else if (count == 2)
		  ta[temp_pos].print ();
		else
		{
		  temp_val = ta[temp_pos].find (word[2]);
		  cout << word[2] << "  " << temp_val << endl;
		}
	  }
	}
	else
	{
	  cout << "Invalid arguements." << endl;
	  return invalid_arg;
	}
	count = fr.next (word, 100);
  } // end while
  fr.close ();
  return no_error;
}

Vector* Command_processor::find_vec (string name)
{
  int i;
  Vector *Not_Found = NULL;

  for (i = 0; i < nv_pos; i++)
	if (nv[i].get_name () == name)
	  return &nv[i];

  for (i = 0; i < cv_pos; i++)
	if (cv[i].get_name () == name)
	  return &cv[i];

  return Not_Found;
}